package com.recharge.service.httpInterFace;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.recharge.common.result.ResultDO;
import com.recharge.common.result.ResultSupport;
import com.recharge.common.util.Constant;
import com.recharge.common.util.MD5Util;
import com.recharge.common.util.TemplateUtils;
import com.recharge.common.util.http.HttpClientUtil;
import com.recharge.domain.query.OrderStatusQueryDO;
import com.recharge.domain.vo.GoodsChannelDO;
import com.recharge.domain.vo.ProviderApiDO;
import com.recharge.domain.vo.ProviderCallbackDO;
import com.recharge.service.ProviderApiService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <h1>上游请求(久雅)</h1>
 *
 * @author kui
 * @date 2020.11.10
 */
@Service
public class JiuYaHTTPImpl implements ProviderHTTPService {

    private Logger logger = LoggerFactory.getLogger(this.getClass().getName());

    @Autowired
    ProviderApiService providerApiService;

    @Override
    public ResultDO commitOrder(GoodsChannelDO domain) {
        // 参数验证
        if (!verifyCommitParam(domain)) {
            return returnFail(false
                    , Constant.BUSINESS_RECHARGE_RETURN_STATUS_FAIL
                    , String.format("订单提交 >> 参数缺失 %s", domain.toString())
                    , "请求参数缺失"
                    , null);
        }

        ProviderCallbackDO callbackDO = new ProviderCallbackDO();
        callbackDO.setSerialNumber(domain.getProviderSerialNumber());
        callbackDO.setProviderId(domain.getProviderId());
        callbackDO.setOrderNo(domain.getOrderNo());
        callbackDO.setStatus(Constant.CALL_BACK_PROCESS);
        ResultDO result = providerApiService.addCallback(callbackDO);
        if (!result.isSuccess()) {
            return returnFail(false
                    , Constant.BUSINESS_RECHARGE_RETURN_STATUS_FAIL
                    , String.format("订单提交 >> 订单%s添加存根信息失败", domain.getProviderSerialNumber())
                    , "添加回调存根信息失败"
                    , null);
        }

        Map<String,String> paramMap = new LinkedHashMap<>();
        // 请求商户号
        String userId = domain.getUserId();
        // 商品编号(测试产品 102144 1元)
        String productId = domain.getProviderGoodsNo();
        // 充值金额面值(元)
        Long price = domain.getAmount() / 1000;
        // 数量
        String num = "1";
        // 充值号码
        String mobile = domain.getRechargeNumber();
        // 流水号
        String sporderId = domain.getProviderSerialNumber();
        // 回调地址
        String backUrl = domain.getCallback();

        paramMap.put("userid", userId);
        paramMap.put("productid", productId);
        paramMap.put("price", String.valueOf(price));
        paramMap.put("num", num);
        paramMap.put("mobile", mobile);

        String afterSign;
        try {
            // 请求时间
            String sporderTime = new SimpleDateFormat("YYYY-MM-DD HH:MM:SS").format(new Date());

            paramMap.put("spordertime", sporderTime);
            paramMap.put("sporderid", sporderId);

            afterSign = MD5Util.md5NoSort(paramMap, domain.getPrivateKey());
        } catch (Exception e) {
            return returnFail(false
                    , Constant.BUSINESS_RECHARGE_RETURN_STATUS_FAIL
                    , String.format("渠道商ID: %s HTTP请求参数构建失败", domain.getProviderId())
                    , "HTTP请求参数构建失败"
                    , null);
        }

        paramMap.put("back_url", backUrl);
        paramMap.put("sign",afterSign);

        // 发送请求
        logger.warn(String.format("订单提交 >> 发送POST请求(订单号%s): %s 参数 %s", domain.getProviderSerialNumber(), domain.getRequestUrl(), paramMap.toString()));
        String sendResult = HttpClientUtil.doPost(domain.getRequestUrl(), paramMap);
        switch (sendResult) {
            case "500":
                return returnFail(false
                        , Constant.BUSINESS_RECHARGE_RETURN_STATUS_FAIL
                        , String.format("订单提交 >> 订单 %s -> 订单提交供货商HTTP请求失败", domain.getProviderSerialNumber())
                        , "HTTP请求失败"
                        , sendResult);
            case "504":
                return returnFail(false
                        , Constant.BUSINESS_RECHARGE_RETURN_STATUS_OUT_TIME
                        , String.format("订单提交 >> 订单 %s -> 订单提交供货商HTTP请求超时", domain.getProviderSerialNumber())
                        , "HTTP请求超时"
                        , sendResult);
            case "":
                return returnFail(false
                        , Constant.BUSINESS_RECHARGE_RETURN_STATUS_OUT_TIME
                        , String.format("订单提交 >> 订单 %s -> 订单提交供货商HTTP请求没有返回信息", domain.getProviderSerialNumber())
                        , "HTTP请求失败"
                        , sendResult);
        }
        logger.warn(String.format("订单提交 >> 请求返回信息: 订单 %s -> %s", domain.getProviderSerialNumber(), sendResult));

        // 解析请求返回结果转换为json对象
        JSONObject resultJson = new JSONObject();
        try {
            resultJson = TemplateUtils.xml2Json(sendResult);
        } catch (Exception e) {
            logger.debug(String.format("订单提交 >> 请求返回结果解析XML失败: %s", sendResult));
        }
        if (resultJson.size() == 0) {
            return returnFail(false
                    , Constant.BUSINESS_RECHARGE_RETURN_STATUS_OUT_TIME
                    , String.format("订单提交 >> 订单 %s -> 订单提交没有返回信息", domain.getProviderSerialNumber())
                    , "没有返回信息"
                    , sendResult);
        }

        String code = null;
        if (resultJson.get("resultno") != null) {
            code = resultJson.getString("resultno");
        }
        if (code == null) {
            return returnFail(false
                    , Constant.BUSINESS_RECHARGE_RETURN_STATUS_OUT_TIME
                    , String.format("订单提交 >> 订单 %s -> 没有获取到返回状态码", domain.getProviderSerialNumber())
                    , "订单提交没有返回状态码"
                    , sendResult);
        }

        // 失败状态
        HashMap<String, String> failMap = new HashMap<>();
        failMap.put("9", "充值失败已退款");
        failMap.put("5001", "代理商不存在");
        failMap.put("5002", "代理商余额不足");
        failMap.put("5003", "此商品暂时不可购买");
        failMap.put("5004", "充值号码与所选商品不符");
        failMap.put("5005", "充值请求验证错误");
        failMap.put("5008", "交易亏损不能充值");
        failMap.put("5009", "Ip不符");
        failMap.put("5010", "商品编号与充值金额不符");
        failMap.put("5011", "商品数量不支持");
        failMap.put("5012", "缺少必要参数或参数值不合法");

        // 未确认状态
        HashMap<String, String> unKnowMap = new HashMap<>();
//        unKnowMap.put("0", "等待充值");
//        unKnowMap.put("2", "充值中");
        unKnowMap.put("5006", "代理商订单号重复");
        unKnowMap.put("5007", "所查询的订单不存在");
        unKnowMap.put("9999", "未知错误,需进入平台查询核实");

        if (code.equals("0") || code.equals("2")) {
            result.setModel(ResultDO.FIRST_MODEL_KEY, Constant.BUSINESS_RECHARGE_RETURN_STATUS_SUCCESS);
            result.setModel(ResultDO.SECOND_MODEL_KEY, "");
            result.setModel(ResultDO.THIRD_MODEL_KEY, "提交成功");
            return result;
        }
        String message = failMap.get(code);
        if (message != null) { //提交失败
            return returnFail(true
                    , Constant.BUSINESS_RECHARGE_RETURN_STATUS_FAIL
                    , String.format("订单提交 >> 订单%s %s", domain.getProviderSerialNumber(), message)
                    , String.format("%s %s", message, code)
                    , sendResult);
        }
        message = unKnowMap.get(code);
        if (message != null) {// 未确认
            return returnFail(true
                    , Constant.BUSINESS_RECHARGE_RETURN_STATUS_OUT_TIME
                    , String.format("订单提交 >> 订单%s %s", domain.getProviderSerialNumber(), message)
                    , String.format("%s %s", message, code)
                    , sendResult);
        }
        return returnFail(true
                , Constant.BUSINESS_RECHARGE_RETURN_STATUS_OUT_TIME
                , String.format("订单提交 >> 订单 %s -> 订单未知|%s", domain.getProviderSerialNumber(), code)
                , code
                , sendResult);

    }

    @Override
    public ResultDO backOrder(ProviderApiDO domain, String paramStr, String bodyStr) {
        ResultDO result = new ResultSupport();
        JSONObject jsonObject = null;
        try {
            jsonObject = JSONObject.parseObject(paramStr, Feature.OrderedField);
            logger.debug("订单异步回调 >> " + domain.getProviderNo() + "解析后数据: " + jsonObject.toJSONString());
        } catch (Exception e) {
            logger.debug("订单异步回调 >> " + domain.getProviderNo() + "解析json失败:" + paramStr);
        }
        if (jsonObject == null) {
            logger.debug("订单异步回调 >> 收到异步回调,但是没有回调信息");
            result.setSuccess(false);
            result.setModel(ResultDO.FIRST_MODEL_KEY, "fail");
            return result;
        }

        // 获取参数
        String orderNo,userId,merchantSubmitTime, serialNum, status, returnSign, voutcher = "";
        try {
            // 时间
            merchantSubmitTime = jsonObject.getString("merchantsubmittime");
            // 商户账号
            userId = jsonObject.getString("userid");
            //上游流水号
            orderNo = jsonObject.getString("orderid");
            //平台流水号
            serialNum = jsonObject.getString("sporderid");
            //状态
            status = jsonObject.getString("resultno");
            // 回调签名
            returnSign = jsonObject.getString("sign");
            //充值凭证
            if (!TemplateUtils.isEmpty(jsonObject.get("othorderid"))) {
                voutcher = jsonObject.getString("othorderid");
            }
        } catch (Exception e) {
            logger.debug("订单异步回调 >> 获取返回结果异常" + e.getMessage());
            result.setSuccess(false);
            result.setModel(ResultDO.FIRST_MODEL_KEY, "fail");
            return result;
        }

        //加密前签名
        String beforeVerifySign = String.format("userid=%s&orderid=%s&sporderid=%s&merchantsubmittime=%s&resultno=%s&key=%s"
                ,userId, orderNo, serialNum, merchantSubmitTime, status, domain.getPrivateKey());

        String afterVerifySign = "";
        try {
            afterVerifySign = MD5Util.md5(beforeVerifySign, 32).toUpperCase();
        } catch (Exception e) {
            logger.debug("订单异步回调 >> 订单(" + serialNum + ")验签加密失败" + e.getMessage());
        }
//        logger.debug("签名验证: after >>"+afterVerifySign);
        if (!afterVerifySign.equals(returnSign)) {
            logger.debug("订单异步回调 >> 签名校验: 加密前 >>" + beforeVerifySign);
            logger.debug(String.format("订单异步回调 >> 订单:%s 签名校验不一致 {本地签名:%s 返回签名:%s }", serialNum, afterVerifySign, returnSign));
            result.setModel(ResultDO.FIRST_MODEL_KEY, "fail");
            return result;
        }

        // 失败状态
//        HashMap<String, String> failMap = new HashMap<>();
//        failMap.put("9", "充值失败已退款");
//        failMap.put("5001", "代理商不存在");
//        failMap.put("5002", "代理商余额不足");
//        failMap.put("5003", "此商品暂时不可购买");
//        failMap.put("5004", "充值号码与所选商品不符");
//        failMap.put("5005", "充值请求验证错误");
//        failMap.put("5008", "交易亏损不能充值");
//        failMap.put("5009", "Ip不符");
//        failMap.put("5010", "商品编号与充值金额不符");
//        failMap.put("5011", "商品数量不支持");
//        failMap.put("5012", "缺少必要参数或参数值不合法");
//
//        // 未确认状态
//        HashMap<String, String> unKnowMap = new HashMap<>();
//        unKnowMap.put("0", "等待充值");
//        unKnowMap.put("2", "充值中");
//        unKnowMap.put("5006", "代理商订单号重复");
//        unKnowMap.put("5007", "所查询的订单不存在");
//        unKnowMap.put("9999", "未知错误,需进入平台查询核实");

        String[] failArray = {"9", "5001", "5002", "5003", "5004", "5005", "5008", "5009", "5010", "5011", "5012"};

        if (status.equals("1")) {//充值成功
            logger.debug(String.format("订单异步回调 >> 订单异步返回:%s 成功 status: %s", serialNum, status));
            result = providerApiService.updateCallback(serialNum, voutcher, orderNo, Constant.CALL_BACK_SUCCESS);
        } else if (Arrays.asList(failArray).contains(status)) { // 充值失败
            logger.debug(String.format("订单异步回调 >> 订单异步返回:%s 失败 status: %s", serialNum, status));
            result = providerApiService.updateCallback(serialNum, "", orderNo, Constant.CALL_BACK_FAIL);
        }else {
            logger.debug(String.format("订单异步回调 >> 订单异步返回:%s 未确认 status: %s", serialNum, status));
            result = providerApiService.updateCallback(serialNum, "", orderNo, Constant.CALL_BACK_NUKNOW);
        }
        if (!result.isSuccess()) {
            logger.debug("订单异步回调 >> 更新订单(" + serialNum + ")状态失败");
            result.setModel(ResultDO.FIRST_MODEL_KEY, "fail");
            return result;
        }
        result.setModel(ResultDO.FIRST_MODEL_KEY, "OK");
        return result;

    }

    @Override
    public ResultDO queryOrder(OrderStatusQueryDO domain) {
        ResultDO result = new ResultSupport();
        if (TemplateUtils.isEmpty(domain.getSerialNo())
                || TemplateUtils.isEmpty(domain.getUserId())) {
            logger.debug(String.format("查询订单 >> 订单 %s -> 没有订单号", domain.toString()));
            result.setSuccess(false);
            result.setModel(ResultDO.THIRD_MODEL_KEY, "请求参数缺失");
            return result;
        }

        String param = String.format("userid=%s&sporderid=%s", domain.getUserId(), domain.getSerialNo());

        // 发送请求
        logger.debug(String.format("查询订单 >> 发送POST请求(订单号%s): url %s?%s", domain.getSerialNo(), domain.getOrderFindUrl(), param));
        String sendResult = HttpClientUtil.doPost(domain.getOrderFindUrl() + "?" + param);
        switch (sendResult) {
            case "500":
                logger.debug(String.format("查询订单 >> 订单 %s -> HTTP请求失败|500", domain.getSerialNo()));
                result.setSuccess(false);
                result.setModel(ResultDO.THIRD_MODEL_KEY, "HTTP请求失败");
                return result;
            case "504":
                logger.debug(String.format("查询订单 >> 订单 %s -> HTTP请求超时|504", domain.getSerialNo()));
                result.setSuccess(false);
                result.setModel(ResultDO.THIRD_MODEL_KEY, "HTTP请求超时");
                return result;
            case "":
                logger.debug(String.format("查询订单 >> 订单 %s -> 请求没有返回信息", domain.getSerialNo()));
                result.setSuccess(false);
                result.setModel(ResultDO.THIRD_MODEL_KEY, "请求没有返回信息");
                return result;
        }

        logger.debug(String.format("查询订单 >> 请求返回信息: 订单 %s -> %s", domain.getSerialNo(), sendResult));

        // 解析请求返回结果转换为json对象
        JSONObject resultJson = new JSONObject();
        try {
            resultJson = TemplateUtils.xml2Json(sendResult);
        } catch (Exception e) {
            logger.debug(String.format("查询订单 >> 请求返回结果解析XML失败: %s", sendResult));
        }
        if (resultJson.size() == 0) {
            logger.debug("查询订单 >> 未找到请求返回结果");
            result.setSuccess(false);
            result.setModel(ResultDO.THIRD_MODEL_KEY, "未找到请求返回结果");
            return result;
        }

        String code = resultJson.get("resultno") == null ? null : resultJson.getString("resultno");
        String voucher = resultJson.get("othorderid") == null ? "" : resultJson.getString("othorderid");
        if (code == null) {
            logger.debug("查询订单 >> 未获取到返回状态码");
            result.setSuccess(false);
            result.setModel(ResultDO.THIRD_MODEL_KEY, "未获取到返回状态码");
            return result;
        }

        // 失败状态
        HashMap<String, String> failMap = new HashMap<>();
        failMap.put("9", "充值失败已退款");
        failMap.put("5001", "代理商不存在");
        failMap.put("5002", "代理商余额不足");
        failMap.put("5003", "此商品暂时不可购买");
        failMap.put("5004", "充值号码与所选商品不符");
        failMap.put("5005", "充值请求验证错误");
        failMap.put("5008", "交易亏损不能充值");
        failMap.put("5009", "Ip不符");
        failMap.put("5010", "商品编号与充值金额不符");
        failMap.put("5011", "商品数量不支持");
        failMap.put("5012", "缺少必要参数或参数值不合法");

        // 未确认状态
        HashMap<String, String> unKnowMap = new HashMap<>();
        unKnowMap.put("5006", "代理商订单号重复");
        unKnowMap.put("5007", "所查询的订单不存在");
        unKnowMap.put("9999", "未知错误,需进入平台查询核实");

        if (code.equals("1")) { //成功
            logger.debug(String.format("查询订单 >> 订单 %s -> 订单成功", domain.getSerialNo()));
            result.setModel(ResultDO.FIRST_MODEL_KEY, Constant.CALL_BACK_SUCCESS);
            result.setModel(ResultDO.SECOND_MODEL_KEY, voucher);
            result.setModel(ResultDO.THIRD_MODEL_KEY, "充值成功");
        }else if (code.equals("2") || code.equals("0")){
            logger.debug(String.format("查询订单 >> 订单 %s -> 订单充值中", domain.getSerialNo()));
            result.setModel(ResultDO.FIRST_MODEL_KEY, Constant.CALL_BACK_PROCESS);
            result.setModel(ResultDO.THIRD_MODEL_KEY, "订单充值中");
        }else if (code.equals("5007")){
            logger.debug(String.format("查询订单 >> 订单 %s -> 订单不存在", domain.getSerialNo()));
            result.setModel(ResultDO.FIRST_MODEL_KEY, Constant.CALL_BACK_NOT_EXIST);
            result.setModel(ResultDO.THIRD_MODEL_KEY, "订单不存在");
            result.setModel(ResultDO.FOURTH_MODEL_KEY, 5);
        } else if (failMap.get(code) != null) {//失败
            logger.debug(String.format("查询订单 >> 订单 %s -> 订单失败|%s", domain.getSerialNo(), failMap.get(code)));
            result.setModel(ResultDO.FIRST_MODEL_KEY, Constant.CALL_BACK_FAIL);
            result.setModel(ResultDO.THIRD_MODEL_KEY, failMap.get(code));
        } else if (unKnowMap.get(code) != null) {//待确认
            logger.debug(String.format("查询订单 >> 订单 %s -> 订单待确认|%s", domain.getSerialNo(), unKnowMap.get(code)));
            result.setModel(ResultDO.FIRST_MODEL_KEY, Constant.CALL_BACK_NUKNOW);
            result.setModel(ResultDO.THIRD_MODEL_KEY, unKnowMap.get(code));
        } else {//未知
            logger.debug(String.format("查询订单 >> 订单 %s -> 订单未知", domain.getSerialNo()));
            result.setModel(ResultDO.FIRST_MODEL_KEY, Constant.CALL_BACK_NUKNOW);
            result.setModel(ResultDO.THIRD_MODEL_KEY, "未知的状态码 " + code);
        }
        return result;
    }

    @Override
    public ResultDO queryBalance(ProviderApiDO domain) {
        ResultDO result = new ResultSupport();
        // 参数验证
        if (domain.getPrivateKey() == null || domain.getUserId() == null) {
            result.setSuccess(false);
            result.setModel(ResultDO.FIRST_MODEL_KEY, "查询失败");
            return result;
        }
        String param = "userid=" + domain.getUserId();
        try {
            String sign = MD5Util.md5(param + "&key=" + domain.getPrivateKey());
            param += "&sign=" + sign;
        } catch (Exception e) {
            logger.debug("余额查询 >> 签名加密失败" + e.getMessage());
            result.setSuccess(false);
            result.setModel(ResultDO.FIRST_MODEL_KEY, "签名加密失败");
            return result;
        }

        // 发送请求, 返回信息编码为gb2312 项目使用编码utf8
        String sendResult = HttpClientUtil.doPost(domain.getBalanceFindUrl() + "?" + param);
        logger.debug(String.format("余额查询 >> 余额查询返回信息: 供应商账号 %s -> %s", domain.getUserId(), sendResult));

        if (TemplateUtils.isEmpty(sendResult)) {
            result.setSuccess(false);
            logger.debug(String.format("余额查询 >> 供应商账号: %s -> 余额查询没有返回信息", domain.getUserId()));
            result.setModel(ResultDO.FIRST_MODEL_KEY, "查询失败");
            return result;
        }
        // 解析请求返回结果转换为json对象
        JSONObject resultJson = new JSONObject();
        try {
            resultJson = TemplateUtils.xml2Json(sendResult);
        } catch (Exception e) {
            logger.debug(String.format("余额查询 >> 请求返回结果解析XML失败: %s", sendResult));
        }
        if (resultJson.size() == 0) {
            result.setSuccess(false);
            logger.debug(String.format("余额查询 >> 供应商账号: %s -> 余额查询没有返回信息", domain.getUserId()));
            result.setModel(ResultDO.FIRST_MODEL_KEY, "查询失败");
            return result;
        }
        String balance;
        if (TemplateUtils.isEmpty(resultJson.get("balance"))) {
            logger.debug(String.format("余额查询 >> 获取余额失败: 供应商账号%s -> %s", domain.getUserId(), sendResult));
            balance = "查询失败";
        } else {
            balance = resultJson.getString("balance");

            // 单位换算
//            StringBuilder buffer = new StringBuilder(resultJson.getString("balance"));
//            buffer.insert(buffer.length() - 3, '.');
//            balance = buffer.toString();
        }

        result.setModel(ResultDO.FIRST_MODEL_KEY, balance);
        return result;
    }

    /**
     * <h2>提交订单返回失败</h2>
     *
     * @param success    是否处理成功
     * @param code       订单状态
     * @param logMessage 失败信息
     * @param message    供货摘要
     * @param entity     返回信息字符串
     * @return FIRST_MODEL_KEY: 订单状态
     * SECOND_MODEL_KEY: 供货摘要
     * THIRD_MODEL_KEY: 上游返回信息字符串
     */
    private ResultDO returnFail(boolean success, int code, String logMessage, String message, String entity) {
        ResultDO result = new ResultSupport();
        result.setSuccess(success);
        result.setModel(ResultDO.FIRST_MODEL_KEY, code);
        result.setModel(ResultDO.SECOND_MODEL_KEY, message);
        result.setModel(ResultDO.THIRD_MODEL_KEY, entity);
        logger.debug(logMessage);
        return result;
    }

    /**
     * 验证提交参数
     *
     * @param domain
     * @return boolean
     */
    private boolean verifyCommitParam(GoodsChannelDO domain) {
        // 密钥
        if (TemplateUtils.isEmpty(domain.getPrivateKey())) {
            return false;
        }
        // 流水号
        if (TemplateUtils.isEmpty(domain.getProviderSerialNumber())) {
            return false;
        }
        // 商户ID
        if (TemplateUtils.isEmpty(domain.getProviderId())) {
            return false;
        }
        // 上游账号
        if (TemplateUtils.isEmpty(domain.getUserId())) {
            return false;
        }
        // 商品编号
        if (TemplateUtils.isEmpty(domain.getProviderGoodsNo())) {
            return false;
        }
        // 面值
        if (TemplateUtils.isEmpty(domain.getAmount())) {
            return false;
        }
        // 充值号码
        if (TemplateUtils.isEmpty(domain.getRechargeNumber())) {
            return false;
        }
        // 回调地址
        if (TemplateUtils.isEmpty(domain.getCallback())) {
            return false;
        }
        // 请求地址
        if (TemplateUtils.isEmpty(domain.getRequestUrl())) {
            return false;
        }

        return true;
    }

    public static void main(String[] args) {
//        double dou = 0.4368;
//        String douStr = String.format("%.3f", dou);
        String a = "SGrXozU2HaYKA8+Hyo4zUXj2pTk6IcSQxU4MsXLowkEnE1WzhX13Z6ZLEga0vVAPgTUdVw6STubJnEtkOVbdl1aLeEEDx+kYMhhYAHBe9zTIhMC603sMjK13yWTSxi3yF0DyUIG8BQ9/Rqk5ZH53sCeTzu+aAgU3/C5XA0oEMj2c4dXz72z5LW3TtdDIVVWlG0HHTpjwHh70zmdtGUwnhbt9oXuHT1kynPZofYbxsgiYZdnKZkcfsB5kP33lHukN3wtqmhWepmhxjwdqeR5UvCBl6N34lHOgHn9mYWUjDyYpAR6fL3S3B9U/pF53a/OeY3kRfju3G78E/e56xL2dsER6g9lQKiFCLbhJWhsPqD1nrO90mnBckbtoLT7OSv98PDzFdeAmANymYxFX7CTgWp3UY5+u8IPKFvGe7buSV3rbbY2q+vFs7USnA8/D5+KoMk86hn/BPKbN6jbFVHlbRLsvJa+0B+O5RruBwmmEbJKpct/Kk9Kib7XgpccsxV/8Mqi4QMKHQ77jlPblwV9cpD1aR1Y7VmNZ5aRgQ0UrqdQ6iszCz8eE8fd+QD8cB6JOfjeqbUb8AfUQwFsYEvz9Pxq7gVNj1R6LGFATZ3S+qJEiqzYxi+rQvbTr106S1UeAt9gBx5LsjLfmh7IZQMsvZkIsDg1wS8PE1VPgYCzMFKlsPd2JhGpqddZWRgXYal4X/mHnjVooZNC1SgkHVa1puxzZSDZ5LBpfSonAePlfVrjfALwVAtsBPkaw5ryAw3xap3Q4976cIrlE+cQjpGN/nMYoNfnWqltMK7v4z+t7xcS45OWgv23n2alFHQCt/+nulg0+ATjL6wesxvw1H369Cp/eKXnisEaVfk5nwVvE6FLZ12FTSsn7MolOz592zxxArdf9F2+GUBhciPgAZ+PaZEMOS97pKMabMxRJGp0qMGLtzuYsYTtH8l8RVuvh82WlbycMYiuT+CwNpscWkcoQH7PsYzqZVAY+XQWXlBjaCUthFrZh8hJHHSSG5wBznXeY/56Rc+tAIMt26e5I1pYCmzbK6Nl0tYxMPy56YKMvpDAZb5FvY/Y40JafPeVdMZ7/dqKPXxofC4nwYDiblYqugYhokAYwBVEK1T3b/OX+SWGSAXx5hswn/PX1BmXTOV55iQ0Ucl1LTJfd9oJZ/AJrSkRBMED4V60CmrwEKWZixKOT2+z0SbB4k+QEj2k/PsqPLjYtVAWC0SJ5hsMSns4nLRjZHr5tKVGaFrJr7ZS0oXVdJn/Db8CkpJs22x+Xarf/hQT80GnjvBY=";

        System.out.println(UUID.randomUUID().toString().replace("-", ""));

    }
}
